package com.keyroy.game.puzzle_rpg.views;

import java.awt.Point;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.widgets.Composite;

import com.keyroy.game.puzzle_rpg.models.animations.TilesAnimationUtil;
import com.keyroy.game.puzzle_rpg.models.environment.Battle;
import com.keyroy.game.puzzle_rpg.models.interfaces.AnimationListener;
import com.keyroy.game.puzzle_rpg.models.interfaces.Repaintable;
import com.keyroy.game.puzzle_rpg.models.interfaces.TilesListener;
import com.keyroy.game.puzzle_rpg.models.puzzle.Result;
import com.keyroy.game.puzzle_rpg.models.render.BattleRender;
import com.keyroy.game.puzzle_rpg.models.role.Role;

public class BattleView extends Composite implements Repaintable {
	private Battle battle;
	private BattleRender battleRender;
	private Role role;
	private boolean isRunningAction;

	public BattleView(Composite parent, final Battle battle) {
		super(parent, SWT.DOUBLE_BUFFERED | SWT.BORDER);
		addPaintListener(new PaintListener() {
			@Override
			public void paintControl(PaintEvent e) {
				if (battleRender != null) {
					battleRender.onDraw(e.gc);
				}
			}
		});

		addMouseListener(new MouseListener() {
			Point out = new Point();

			@Override
			public void mouseUp(MouseEvent e) {
				mouseDown(e);
			}

			@Override
			public void mouseDown(MouseEvent e) {
				cancelTips();
				out.setLocation(e.x, e.y);
				if (isRunningAction == false && battle != null && battleRender.inMapRect(out)) {
					battleRender.toMapRect(e.x, e.y, out);
					battle.onPointerDown(getTilesListener(), out.x, out.y);
				}
				repaint();
			}

			@Override
			public void mouseDoubleClick(MouseEvent e) {

			}
		});
		setBattle(battle);
		turnNex();
	}

	private void turnNex() {
		if (role == null) {
			role = battle.getAllies().get(0);
		} else {
			role.setTurn(false);
			int aIndex = battle.getAllies().indexOf(role);
			int eIndex = battle.getEnemies().indexOf(role);

			if (aIndex != -1) {
				role = battle.getEnemies().get(aIndex);
			} else if (eIndex != -1) {
				aIndex = eIndex + 1;
				if (aIndex >= battle.getAllies().size()) {
					aIndex = 0;
				}
				role = battle.getAllies().get(aIndex);
			}
		}

		if (role != null) {
			role.setTurn(true);
		}
		repaint();
	}

	private TilesListener tileListener;

	private TilesListener getTilesListener() {
		if (tileListener == null) {
			tileListener = new TilesListener() {
				boolean size4 = false;

				@Override
				public void onClean(List<Result> results) {
					if (results != null && role != null) {
						for (int i = 0; i < results.size(); i++) {
							Result result = results.get(i);
							role.getTilesRecord().add(result.tileType, result.points.size());
							if (result.points.size() > 3) {
								size4 = true;
							}
						}

					}
				}

				@Override
				public void onComplete() {
					if (size4 == false) {
						turnNex();
					}
					size4 = false;
				}
			};
		}
		return tileListener;
	}

	private void setBattle(Battle b) {
		this.battle = b;
		if (battle != null) {
			battleRender = new BattleRender(battle);
			if (battle.battleScene == null || battle.battleScene.isHorizontal()) {
				setSize(854, 480);
			} else {
				setSize(480, 854);
			}
			TilesAnimationUtil.init(this, battle.puzzleMap);
			TilesAnimationUtil.startMove(new AnimationListener() {
				@Override
				public void onStart() {
					isRunningAction = true;
				}

				@Override
				public void onComplete() {
					isRunningAction = false;
				}
			});
		}
	}

	public Battle getBattle() {
		return battle;
	}

	public void tips() {
		battleRender.tips();
		repaint();
	}

	public void cancelTips() {
		battleRender.cancelTips();
		repaint();
	}

	@Override
	protected void checkSubclass() {
	}

	@Override
	public void repaint() {
		getDisplay().asyncExec(new Runnable() {
			@Override
			public void run() {
				redraw();
			}
		});
	}

}
